package com.dev.print.protocol;

import android.util.Log;

import com.dev.print.protocol.base.SPConfig;
import com.dev.print.protocol.callback.ReadFrameCallback;
import com.dev.print.utils.LogUtils;
import com.dev.print.utils.ParseTools;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;


public class RtcFrameThread extends Thread {
    ReadFrameCallback mReadFrameCallback;
    ReadWriteFrame mReadWriteFrame;

    byte[] mFrameTopEnd = {(byte) 0x68, (byte) 0x16};
    ByteArrayOutputStream mOutputStream = null;
    boolean finished;
    private Queue<Byte> mQueByteRead;
    ;
    Queue<byte[]> mLinkedQueue;

    public RtcFrameThread(ReadFrameCallback paramReadFrameCallback, ReadWriteFrame paramReadWriteFrame) {
        super();
        mReadFrameCallback = paramReadFrameCallback;
        mReadWriteFrame = paramReadWriteFrame;
        mOutputStream = new ByteArrayOutputStream();
        mQueByteRead = new LinkedBlockingQueue<>();
        mLinkedQueue = new LinkedBlockingQueue<>();
    }

    public boolean register(SPConfig paramConfig) {
        if (mReadWriteFrame.registerSP(paramConfig))
            return true;
        return false;
    }

    public int write(byte[] buffer) {
        LogUtils.d("data(原始数据):" + buffer.length + "-----" + ParseTools.byteToString(buffer).toString());
        return mReadWriteFrame.writeRtcFrame(buffer);
    }

    @Override
    public void run() {
        super.run();
        while (!finished && null != mReadFrameCallback) {
            byte[] buffer = mReadWriteFrame.readRtcFrame();
            if (null != buffer && buffer.length > 0) {
                mReadFrameCallback.rtcFrameCallback(buffer);
                try {
                    checkData(buffer);
                } catch (Exception e) {
                    Log.e(RtcFrameThread.class.getName(), Log.getStackTraceString(e));
                }
            }
            try {
                sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    protected boolean isFrameHead = false;
    protected int frameLength = 0;

    public void checkData(byte[] data) {
        LogUtils.d("data(原始数据):" + data.length + "-----" + ParseTools.byteToString(data).toString());
        int len = data.length;
        if (len > 0) {
            for (int j = 0; j < len; j++) {
                if (isFrameHead) {
                    //低位在前
//                    frameLength = data[j + 3];
//                    if (j < len - 4 && data[j + 4] != 0x00)
//                        frameLength = data[j + 4] * 256 + frameLength + 8;
                    //高位在前
                    frameLength = data[j + 3] * 256;
                    if (j < len - 4 && data[j + 4] != 0x00)
                        frameLength = data[j + 4] + frameLength + 8;
                    isFrameHead = false;
                    LogUtils.d("data length:" + frameLength);
                }
                if (data[j] == (byte) 0x68) {
                    LogUtils.d("data:读到0x68头了");
                    isFrameHead = true;
                    if (mQueByteRead.size() >= 1) {
                        LogUtils.d("data:frameLength"+frameLength+";mQueByteRead:"+mQueByteRead.size());
                        if(frameLength!=mQueByteRead.size()){
                            mQueByteRead.clear();
                        }else{
                            synchronizeFrame(mQueByteRead, frameLength);
                        }
                    }
                }
                mQueByteRead.offer(data[j]);

                if (mQueByteRead.size() >= frameLength && frameLength > 0) {
                    LogUtils.d("data:队列中存储的数据大于等于数据长度了");
                    synchronizeFrame(mQueByteRead, frameLength);
                    frameLength = 0;
                }
            }
        }
    }



    protected void synchronizeFrame(Queue<Byte> data, int length) {
        LogUtils.d("data:Queue中的数据:" + data.toString());
        byte[] intactDataFrame = new byte[length];
        int brc = 0;
        for (int i = 0; i < length - 2; i++) {
            intactDataFrame[i] = data.poll();
            if (i == 0) {
                brc = intactDataFrame[i];
            } else {
                brc += intactDataFrame[i];
            }
        }
        intactDataFrame[length - 2] = data.poll();
        intactDataFrame[length-1] = data.poll();

        mLinkedQueue.offer(intactDataFrame);
        LogUtils.d("data(完整一组数据):" + ParseTools.byteToString(intactDataFrame).toString());
        // 校验
        if (((byte) (brc % 256)) == intactDataFrame[length - 2]) {
            synchronized (mLinkedQueue) {
                LogUtils.d("data:校验通过");
                    mReadFrameCallback.completionFrameCallback(mLinkedQueue.poll());
            }
        }
    }

    //关闭;
    public void close() {
        finished = true;
        try {
            if (null != mOutputStream) {
                mOutputStream.close();
            }
        } catch (IOException ex) {
            System.out.println(String.format("ex.getMessage() -->>> %s ex.println() --->>> %s", ex.getMessage(), Log.getStackTraceString(ex)));
        }
    }


}
